home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / dakit / anim2pcx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-24  |  8.4 KB  |  297 lines

  1. /*--anim2pcx.c----------------------------------------------------------
  2.  *
  3.  *    Program to translate an anim into a series of PCX picture files,
  4.  *  and back from picture files into an anim.
  5.  *  Note: all pictures are assumed to have the same 256 palette colors.
  6.  *
  7.  *  This code is intended to be used as a starting point for programmers
  8.  *  needing to convert anims to/from other formats, or to read/write
  9.  *  anim files from their own applications.
  10.  *
  11.  * The source code for ANIM2PCX may be freely incorporated into
  12.  * commercial programs.
  13.  * 
  14.  * Disclaimer:
  15.  *   THIS PROGRAM IS PROVIDED WITHOUT SEPARATE CHARGE AND IS
  16.  *   PROVIDED AS IS.  ELECTRONIC ARTS DISCLAIMS ALL WARRANTIES,
  17.  *   INCLUDING IMPLIED WARRANTIES AND WARRANTIES OF
  18.  *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  19.  *
  20.  * *** History *********
  21.  * Date      Who Changes
  22.  * --------- --- ---------------------------------------------------
  23.  * 24-Oct-90 ss  Original release.
  24.  *------------------------------------------------------------------
  25.  * Note: all files editted with tab stops every 4 spaces.
  26.  */
  27.  
  28. #include "main.h"
  29. #include "anim.h"
  30.  
  31. #include <fcntl.h>
  32. #include <sys\types.h>
  33. #include <sys\stat.h>
  34. #include <io.h>
  35. #include <stdio.h>
  36.  
  37. #define local static
  38.  
  39. extern char lpfSuffix[];
  40. local char pcxSuffix[]= "PCX";
  41.  
  42. BOOL FileError = FALSE;    /* error reading or writing a file */
  43. BOOL EscFlag = FALSE;    /* set TRUE when Esc key detected */
  44.  
  45. LONG curpal[MAX_COLORS];    /* palette */
  46.  
  47. /*-----------------------------------------------------------------*/
  48.  
  49. /* --- array of bit masks for one byte */
  50. BYTE bit_masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
  51.  
  52. BOOL toAnim;
  53. UWORD animFrames = 10;
  54. WORD curFrame = FIRST_FRAME_N;    /* Frame currently in hidbm. */
  55. char animName[FILENAME_ROOT_LENGTH], pictRoot[FILENAME_ROOT_LENGTH];
  56.  
  57. BITMAP hidbm, prevFrame;    /* Bitmap describing current & previous frames.*/
  58. UWORD lpSeg = NULL;        /* Segment of lp buffer. */
  59. UWORD allocSeg = NULL;    /* Segment allocated for delta buffer. */
  60.  
  61. /*-----------------------------------------------------------------*/
  62. /* forward procedure definitions */
  63.  
  64.  
  65. /* --------------- main ---------------
  66.  */
  67. main(argc, argv)
  68. WORD argc;
  69. char *argv[];
  70. {
  71.     WORD result;
  72.     BITMAP bitmap;
  73.  
  74.     /* ----------------------------------------
  75.      * Analyze arguments.
  76.      */
  77.     switch (argc) {
  78.       case 1+1:        /* anim => pcx */
  79.         if (strlen(argv[1]) > FILENAME_ROOT_LENGTH)
  80.             goto usage;
  81.         strcpy(animName, argv[1]);
  82.         toAnim = FALSE;
  83.         break;
  84.       case 2+1:        /* pcx => anim */
  85.         if (strcmp(argv[1],"join") != SUCCESS  &&
  86.             strcmp(argv[1],"j") != SUCCESS)
  87.             goto usage;
  88.         if (strlen(argv[2]) > FILENAME_ROOT_LENGTH)
  89.             goto usage;
  90.         strcpy(animName, argv[2]);
  91.         toAnim = TRUE;
  92.         break;
  93.       default:        /* Bad arguments. */
  94. usage:
  95. #define PR(s)    printf(s)
  96.  PR("\nUsage:\n");
  97.  PR("  \"anim2pcx name\"       to split anim name.ANM into a group of\n");
  98.  PR("                          picture files name0001.PCX, name0002.PCX...\n");
  99.  PR("  \"anim2pcx j name\"     or\n");
  100.  PR("  \"anim2pcx join name\"  to join a group of picture files\n");
  101.  PR("                          name0001.PCX, name0002.PCX, into an anim.\n");
  102.  PR("\n");
  103.  PR("NOTE: Only the first four letters of \"name\" are used \n");
  104.  PR("in the picture file names.\n");
  105.  PR("  \"anim2pcx foobar\"     splits FOOBAR.ANM into FOOB0001.PCX...\n");
  106.  PR("  \"anim2pcx j foobar\"   joins FOOB0001.PCX... into FOOBAR.ANM.\n");
  107.         exit(1);
  108.     }
  109.  
  110.     /* ----------------------------------------
  111.      * Prepare for conversion.
  112.      */
  113.  
  114.     /* --- Pict name's suffix is first four characters of anim name.
  115.      * Note: pictRoot may be shorter than four characters.
  116.      */
  117.     strcpy(pictRoot, animName);
  118.     pictRoot[SEQUENCE_ROOT_LENGTH] = NULL;
  119.  
  120.     NewBitMap(&hidbm, N_COLUMNS, N_LINES);
  121.     NewBitMap(&prevFrame, N_COLUMNS, N_LINES);
  122.     allocSeg = DAlloc(MAX_LARGE_PAGE_SIZE);
  123.     lpSeg = DAlloc(MAX_LARGE_PAGE_SIZE);
  124.     if (!allocSeg || !lpSeg)
  125.         NotEnoughMemExit();
  126.  
  127.     if (toAnim)
  128.         result = PCXFilesToAnimFile();
  129.     else
  130.         result = AnimFileToPCXFiles();
  131.  
  132.     /* ASSUME DAlloc'd memory automatically freed. */
  133.  
  134.     if (EscFlag == TRUE)
  135.         EmergencyExit("Terminated at user's request");
  136.     if (FileError)
  137.         EmergencyExit("File error");
  138.     if (result != SUCCESS)
  139.         EmergencyExit("Failed to complete operation");
  140.     printf("File(s) successfully converted.\n");
  141. }
  142.  
  143. /* --------------- save_picture0 ---------------
  144.  */
  145. UWORD save_picture0(char *filename)
  146. {
  147.     UWORD result, file;
  148.  
  149.     file = CreateFile(filename, pcxSuffix);
  150.     if (!file)   return FAIL;
  151.  
  152.     OpenIOBuffer(TRUE);
  153.     result = WritePCX_Header(file, &hidbm, curpal);
  154.     if (result != SUCCESS)   goto done;
  155.     result = WritePCX_BODY(file, &hidbm);
  156.     if (result != SUCCESS)   goto done;
  157.     result = WritePCX_256Palette(file, curpal);
  158.  
  159. done:
  160.     WritePCX_Done();
  161.     CloseIOBuffer(file);
  162.     closedos(file);
  163.     return result;
  164. }
  165.  
  166. /* --------------- AnimFileToPCXFiles ---------------
  167.  * ASSUMES "animName" already set to the root part of the animation file's
  168.  * name.  (Note: don't include ".ANM" in "animName".)
  169.  */
  170. WORD AnimFileToPCXFiles()
  171. {
  172.     WORD i, len, result = FAIL;
  173.     char nm[FILENAME_LENGTH+1];
  174.     char nstr[SEQUENCE_DIGITS_LENGTH+1];
  175.  
  176.     if (OpenLpFile() == FAIL) {
  177.         printf("File \"%s.%s\" not found.\n", animName, lpfSuffix);
  178.         exit(1);
  179.     }
  180.  
  181.     printf("Creating %d PCX files from \"%s.%s\".\n",
  182.            animFrames, animName, lpfSuffix);
  183.  
  184.     FirstAnimFrame0();
  185.     for (i = 0;  i < animFrames;  i++) {
  186.         strcpy(nm, pictRoot);
  187.         num_to_string_zeroes(curFrame, nstr, SEQUENCE_DIGITS_LENGTH);
  188.         strcat(nm, nstr);
  189.         if (save_picture0(nm) == FAIL)
  190.             goto done;    /* TBD: message to user? */
  191.         printf(".");    /* Inform user of progress. */
  192.         NextAnimFrame0();
  193.         if (CheckAbort())
  194.             goto done;
  195.     }
  196.     printf("\n");    /* Inform user of progress. */
  197.     result = SUCCESS;
  198.  
  199. done:
  200.     return result;
  201. }
  202.  
  203. /* --------------- load_picture0 ---------------
  204.  */
  205. UWORD load_picture0(char *filename)
  206. {
  207.     UWORD result, file;
  208.     BitMapHeader bmHdr;
  209.  
  210.     file = OpenFile(filename, pcxSuffix);
  211.     if (!file)   return FAIL;
  212.  
  213.     OpenIOBuffer(FALSE);
  214.     result = ReadPCX_Header(file, &hidbm, curpal, &bmHdr);
  215.     if (result != SUCCESS)   goto done;
  216.     result = ReadPCX_BODY(file, &hidbm, &bmHdr);
  217.  
  218. done:
  219.     ReadPCX_Done();
  220.     CloseIOBuffer(file);
  221.     closedos(file);
  222.     return result;
  223. }
  224.  
  225. /* --------------- PCXFilesToAnimFile ---------------
  226.  * ASSUMES "animName" already set to the root part of the animation file's
  227.  * name.  (Note: don't include ".ANM" in "animName".)
  228.  */
  229. WORD PCXFilesToAnimFile()
  230. {
  231.     WORD i, file, len, result = FAIL;
  232.     char nm[FILENAME_LENGTH+1];
  233.     char nstr[SEQUENCE_DIGITS_LENGTH+1];
  234.  
  235.     for (i = 0;  i < MAX_SUPPORTED_FRAMES;  i++) {
  236.         strcpy(nm, pictRoot);
  237.         num_to_string_zeroes(i+FIRST_FRAME_N, nstr, SEQUENCE_DIGITS_LENGTH);
  238.         strcat(nm, nstr);
  239.         /* --- Verify file exists, then inform user of operation.*/
  240.         file = OpenFile(nm, pcxSuffix);
  241.         if (!file) {
  242.             if (i == 0) {
  243.                 printf("File \"%s.%s\" not found.\n", nm, pcxSuffix);
  244.                 exit(1);
  245.             } else
  246.                 break;    /* Exit "for i" loop that was adding frames. */
  247.         }
  248.         CloseFile(file);
  249.         if (i == 0) {
  250.             CreateLpFile();
  251.             FirstAnimFrame0();
  252.             printf("Creating \"%s.%s\" from PCX files.\n",
  253.                animName, lpfSuffix);
  254.         } else {
  255.             AddFrame();        /* And make that frame current. */
  256.             far_movmem(BSEG(&hidbm), 0, BSEG(&prevFrame), 0,
  257.                         N_BYTES_IN_BITMAP);
  258.                 /* New frame's "previous frame" has identical contents. */
  259.         }
  260.         if (load_picture0(nm) == FAIL)
  261.             break;        /* No more pictures to load.  NOT an error,
  262.                          * TBD: but should delete last added frame! */
  263.         printf(".");    /* Inform user of progress. */
  264.         WriteFinalAnimFrame();
  265.         if (CheckAbort()) {
  266.             result = SUCCESS;    /* So anim so far will be kept. */
  267.             i++;    /* So correct notion of frame count. */
  268.             goto done;
  269.         }
  270.     }
  271.  
  272.     /* Create last-to-first delta.
  273.      * First create it as a new frame at the end of the anim,
  274.      * then remove it from the frame count and mark the anim
  275.      * as containing a last-to-first delta.
  276.      */
  277.     strcpy(nm, pictRoot);
  278.     num_to_string_zeroes(FIRST_FRAME_N, nstr, SEQUENCE_DIGITS_LENGTH);
  279.     strcat(nm, nstr);
  280.     AddFrame();        /* And make that frame current. */
  281.     far_movmem(BSEG(&hidbm), 0, BSEG(&prevFrame), 0,
  282.                 N_BYTES_IN_BITMAP);
  283.     load_picture0(nm);
  284.     WriteFinalAnimFrame();
  285.     ConvertFinalFrameToLastDelta();
  286.  
  287.     result = SUCCESS;
  288.  
  289. done:
  290.     WriteHdrAndCloseLpFile();
  291.     if (result == SUCCESS)
  292.         printf("\nAnim has %d frames.\n", i);    /* Inform user of progress. */
  293.     else
  294.         DeleteFile(animName, lpfSuffix);
  295.     return result;
  296. }
  297.